<?php
/**
 * Note: *
 * Date: 2019/12/19
 */
namespace App\Services;

use App\Caches\RoleAccessCache;
use App\Caches\RoleCache;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

class AuthService
{
    /**
     * 不要权限就能访问
     * @return array
     */
    public function getIgnorePermissions()
    {
        return [
            'login',
            'logout',
            'index',
            'passport',
            'manager.info',
            'role-access.format',
            'config.index',
            // 'activity-mgr.index',
        ];
    }

    /**
     * 不要权限就能访问的组
     * @return array
     */
    public function getIgnorePermissionGroups()
    {
        return [
            'ignition.',
            'passport.',
            'generated:',
        ];
    }

    /**
     * 路由检查
     * @param Request $request
     * @param $roleAccess /角色拥有的权限
     * @return bool
     */
    private function checkRoute(Request $request, $roleAccess)
    {
        $roleAccess = Arr::pluck($roleAccess, 'id', 'route');
        $curRouteName = $request->route()->getName();

        // 未命名的路由
        if (!$curRouteName) return true;

        // 忽略路由
        if (in_array($curRouteName, $this->getIgnorePermissions())) {
            return true;
        }

        // 匹配超级权限 *
        if (isset($roleAccess['*'])) return true;

        // 匹配模块顶级权限 module.*
        //if (isset($roleAccess[$curRoutePrefix.'*'])) return true;

        // 路由名称完全匹配 module.action
        if (isset($roleAccess[$curRouteName])) return true;

        // 权限表无此路由 直接通过
        if (!RoleAccessCache::routeExists($curRouteName)) {
            return true;
        }

        return false;
    }

    /**
     * 根据当前用户各个角色, 检查路由权限
     * @param Request $request
     * @return bool
     */
    public function canPass(Request $request)
    {
        $user = $request->user();
        if (!$user) return false;

        $pass = false;
        foreach ($user->role as $roleId) {
            $roleAccess = RoleCache::access($roleId);
            if ($this->checkRoute($request, $roleAccess)) {
                $pass = true;
                break;
            }
        }
        return $pass;
    }
}
